package com.webkit.web;

import com.lamfire.logger.Logger;
import com.webkit.web.action.Action;
import com.webkit.web.action.ServletAction;
import com.webkit.web.action.ServletActionResult;
import com.webkit.web.action.StreamAction;
import com.webkit.web.action.TextAction;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class InvocationVisitor {
	static final Logger LOGGER = Logger.getLogger(InvocationVisitor.class);

	public void visitServletAction(ServletAction action) throws ActionException {
		ServletAction sa = action;
		ServletActionResult rt = sa.execute();

		if (rt == null)
			return;

		HttpServletRequest request = ActionContext.getActionContext().getHttpServletRequest();
		HttpServletResponse response = ActionContext.getActionContext().getHttpServletResponse();

		RequestDispatcher rd = request.getRequestDispatcher(rt.getUrlPath());
		try {
			if (rt.isRedirect()) {
				response.sendRedirect(request.getContextPath() + rt.getUrlPath());
				return;
			}
			if ((request instanceof WebKitRequestWrapper)) {
				((WebKitRequestWrapper) request).setAction(action);
			}
			rd.forward(request, response);
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			throw new ActionException(e);
		}
	}

	public void visitStreamAction(StreamAction action) throws ActionException {
		HttpServletResponse response = ActionContext.getActionContext().getHttpServletResponse();
		try {
			StreamAction sa = action;
			sa.execute(response.getOutputStream());
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			throw new ActionException(e);
		}
	}

	public void visitTextAction(TextAction action) throws ActionException {
		HttpServletResponse response = ActionContext.getActionContext().getHttpServletResponse();
		try {
			action.execute(response.getWriter());
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			throw new ActionException(e);
		}
	}

	public void visit(Action action) throws ActionException {
		if ((action instanceof ServletAction)) {
			visitServletAction((ServletAction) action);
			return;
		}

		if ((action instanceof StreamAction)) {
			visitStreamAction((StreamAction) action);
			return;
		}

		if ((action instanceof TextAction)) {
			visitTextAction((TextAction) action);
			return;
		}
	}
}